import { mapState, mapMutations } from 'vuex';

import _ from 'lodash';
import Moment from 'moment';

import { 
    getBaseUrl,
    toast,
    isCurrentClient,
    openUrl,
    formatFileExtension,
    formatFileName,
} from 'common/env';

import Utils from 'common/utils';

export default {
    data() {
        return {
            $$context: '',
        };
    },
    computed: {
        ...mapState([
            'ST_CURRENT', 'ST_DEVICE', 'ST_USER'
        ]),
        $$contextHasInit() {
            if(! this.$$contextName || ! this.$$context || this.ST_CURRENT.loading) {
                return false;
            }
            return true;
        },
    },
    watch: {
        '$$contextName'() {
            this._$$init();
        },
        'ST_CURRENT.loading'(newVal) {
            if(newVal) {
                return;
            }
            _.isFunction(this.$$reload) && this.$$reload();
        },
    },
    methods: {
        ...mapMutations([
            'BIND_USER', 'BIND_CURRENT', 'BIND_DEVICE', 
        ]),
        $$formatTime(sendTimeOrStr) {
            const moment = Moment(sendTimeOrStr);
            let date = moment.toDate();
            let locale = moment.format('YYYY-MM-DD HH:mm');
            let localeDate = moment.format('YYYY-MM-DD');
            let since = moment.fromNow();
            if(since == '几秒前' || since == '几秒内') {
                since = '刚刚';
            } else if(since.indexOf('分钟前') != -1) {
                const number = parseInt(since);
                if(number < 3) {
                    since = '刚刚';
                } else if(number < 10) {
                    since = '几分钟前';
                } else if(number > 30 && number < 60) {
                    since = '半小时前';
                }
            }
            return {
                moment: moment,
                date: date,
                time: date.getTime(),
                locale: locale,
                localeDate: localeDate,
                since: since,
            };
        },
        $$getTimeRange(sendTimeOrStr, type, format = 'YYYY-MM-DD HH:mm:ss') {
            const moment = sendTimeOrStr ? Moment(sendTimeOrStr) : Moment();
            const start = moment.startOf(type);
            const end = moment.endOf(type);
            return {
                start: format ? start.format(format) : start,
                end: format ? end.format(format) : end,
                startTime: start.toDate().getTime(),
                startTime: end.toDate().getTime(),
            };
        },
        $$commonHandleResult(obj, command, results) {
            if(! obj || ! command) {
                return;
            }
            results = results || [];
            if(! obj.rows || command == 'reset') {
                if(obj.rowMap) {
                    _.forEach(results, (result) => {
                        this.$set(obj.rowMap, result.id, result);
                    });
                }
                this.$set(obj, 'rows', results);
                return;
            }
            _.forEach(results, (result) => {
                if(! obj.rowMap) {
                    obj.rows.push(result);
                    return true;
                }
                const oldOne = obj.rowMap[result.id];
                const index = obj.rows.indexOf(oldOne);
                this.$set(obj.rowMap, result.id, result);
                if(! obj.rows) {
                    obj.rows = [];
                }
                if(index != -1) {
                    this.$set(obj.rows, index, result);
                    return true;
                }
                obj.rows.push(result);
            });
        },
        $$getCache(key, cacheType) {
            if(! this.$$contextHasInit || ! key || ! cacheType) {
                return;
            }
            const cacheManager = this.$$context.get(':cache');
            if(! cacheManager) {
                return;
            }
            const cahce = cacheManager.cacheOf(cacheType);
            if(! cahce) {
                return;
            }
            return cahce.get(key);
        },
        $$setCache(obj, cacheType) {
            const cacheManager = this.$$context.get(':cache');
            if(! cacheManager) {
                return;
            }
            const cache = cacheManager.cacheOf(cacheType || obj.prototype);
            if(! cache) {
                return;
            }
            return cache.cache(obj.id, obj);
        },
        $$deleteCache(obj, cacheType) {
            const cacheManager = this.$$context.get(':cache');
            if(! cacheManager) {
                return;
            }
            const cache = cacheManager.cacheOf(cacheType || obj.prototype);
            if(! cache) {
                return;
            }
            return cache.remove(_.isString(obj) ? obj : obj.id);
        },
        $$clearCache() {
            const cacheManager = this.$$context.get(':cache');
            if(! cacheManager) {
                return;
            }
            return cacheManager.clear();
        },
        $$retryTask(taskId) {
            const task = this.$$context.task(taskId);
            if(! task) {
                return;
            }
            task.retry();
        },
        $$cancelTask(taskId) {
            const task = this.$$context.task(taskId);
            if(! task) {
                return;
            }
            task.cancel();
        },
        $$goto(href, query, replace) {
            if(! href) {
                return;
            }
            if(_.startsWith(href, 'http')) {
                if(query) {
                    href = href.indexOf('?') == -1 
                        ? href + '?' + Utils.toQueryStr(query)
                        : href + '&' + Utils.toQueryStr(query);
                }
                openUrl(href, replace);
                return;
            }
            this.$router[replace?'replace':'push']({ path: href, query: query});
        },
        $$popCommand(name) {
            if(! name) {
                return;
            }
            this.BIND_COMMAND({
                name: name,
                command: 'reset',
            });
        },
        $$notifyParentEvent(eventName, data) {
            this.$$pushCommand('FRMAE_NOTIFY', _.merge({
                eventName: eventName,
            }, data));
        },
        $$previewImage(imgObj) {
            if(! imgObj || ! imgObj.url) {
                return;
            }
            this.BIND_CURRENT({ 
                gallerying: this.$$pushCommand('GALLERY', {
                    id: imgObj.id || Utils.hashCode(imgObj.url),
                    name: imgObj.name,
                    url: imgObj.url,
                }),
            });
        },
        $$visitBandObj(objId, args) {
            this.$$runSystemTool(g_refVisitToolId, {
                objID: objId,
                pure: true, // runSystemTool已经处理app的情况了
                args: args
            }, objId);
        },
        $$formatFileExtension(file) {
            return formatFileExtension(file);
        },
        $$formatFileName(file, extension) {
            return formatFileName(file, extension);
        },
        $$getRunToolUrl(toolIdOrAlias, param, args, gid) {
            if(! toolIdOrAlias) {
                return;
            }
            if(param && param.param) {
                args = param;
                param = param.param;
                delete args.param;
            }
            const query = args || {};
            if(_.toString(toolIdOrAlias).match(/^\d+$/)) {
                query.toolID = toolIdOrAlias;
            } else {
                query.alias = toolIdOrAlias;
            }
            gid = gid || param.gid || query.gid ;
            const runToolUrl = gid
                ? window.g_callToolUrl.replace(/gid=(\d+)(?=\&|$)/g, `gid=${gid}`)
                : window.g_callToolUrl;
            if(_.isObject(param)) {
                param = JSON.stringify(param);
            }
            const queryStr = Utils.toQueryStr(query);
            return `${runToolUrl}&param=${encodeURI(_.toString(param || ''))}&${encodeURI(queryStr)}`;
        },
        $$runSystemTool(toolIdOrAlias, param, gid) {
            if(! toolIdOrAlias) {
                return;
            }
            const toolInfo = {};
            const runToolUrl = this.$$getRunToolUrl(toolIdOrAlias, param, toolInfo, gid);
            if(isCurrentClient('wx')) {
                window.open(runToolUrl,  '_top');
            } else if(isCurrentClient('desktop')) {
                window.open(runToolUrl, '_blank');
            } else if(isCurrentClient('mobile')) {
                require('plugin/API').callAppAPI('gotoRunSystemTool', _.merge({
                    toolAlias: toolInfo.alias,
                    param: param,
                }, toolInfo));
            }
        },
        _$$init() {
            // 如果没有指定组件名称则不用处理
            if(! this.$$contextName) {
                return;
            }
            // 即使已经初始化过也要覆盖，保证引用的组件实例一定有效
            this.$$context = this.$inject.to(this, this.$$contextName);
            // 监听一些事件：
            this.$$context.listen('service:beforeInvoke', (params) => {
                
            });
            this.$$context.listen('service:afterFail', (errorMsg, json) => {
                
            });
            this.$$context.listen('service:afterError', (response, json) => {
                if(errorMsg.indexOf('会话超时') != -1) {
                    window.setUserTimeout && window.setUserTimeout();
                }
            });
        },
    },
    mounted() {
        this._$$init();
        if(this.$$contextHasInit) {
            _.isFunction(this.$$reload) && this.$$reload();
        }
    },
    beforeDestroy() {
        if(this.$$context && _.isFunction(this.$$context.unject)) {
            this.$$context.unject();
        }
    },
};